package fr.unice.polytech.chord.samples.managers;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;

import jline.ArgumentCompletor;
import jline.Completor;
import jline.ConsoleReader;
import jline.SimpleCompletor;
import fr.unice.polytech.chord.core.Tracker;
import fr.unice.polytech.chord.samples.commands.Command;
import fr.unice.polytech.chord.samples.commands.GetCommand;
import fr.unice.polytech.chord.samples.commands.JoinCommand;
import fr.unice.polytech.chord.samples.commands.LeaveCommand;
import fr.unice.polytech.chord.samples.commands.ListNodesCommand;
import fr.unice.polytech.chord.samples.commands.PutCommand;
import fr.unice.polytech.chord.samples.commands.QuitCommand;
import fr.unice.polytech.chord.samples.commands.RemoveCommand;

/**
 * @author Laurent Pellegrino
 * 
 * @version 10/30/2009
 */
public class InteractiveManager extends Manager {
	public InteractiveManager(Tracker tracker) {
		super(tracker);

		super.addAction(new JoinCommand(this));
		super.addAction(new LeaveCommand(this));
		super.addAction(new GetCommand(this));
		super.addAction(new PutCommand(this));
		super.addAction(new RemoveCommand(this));
		super.addAction(new ListNodesCommand(this));
		super.addAction(new QuitCommand(this));
	}

	public void printActionsMenu() {
		StringBuffer buf = new StringBuffer();
		buf.append("Select an action to perform from ");
		try {
			buf.append(InetAddress.getLocalHost().getHostName());
		} catch (UnknownHostException e) {
			buf.append("unKnown");
		}
		buf.append(":\n");

		for (Command action : super.getActions()) {
			buf.append("   (*) ");
			buf.append(action.getCommandShortcuts().get(0));

			if (action.getCommandArguments() != null) {
				if (action.getCommandArguments().length > 0) {
					buf.append(" ");
				}

				for (int i = 0; i < action.getCommandArguments().length; i++) {
					buf.append("<");
					buf.append(action.getCommandArguments()[i]);
					buf.append(">");
					if (i != action.getCommandArguments().length - 1) {
						buf.append(" ");
					}
				}
			}

			buf.append(" : ");
			buf.append(action.getDescription());
			buf.append("\n");
		}

		System.out.println(buf.toString());
	}

	public void run() {
		String inputLine;
		ConsoleReader reader = null;
		try {
			reader = new ConsoleReader();
		} catch (IOException e) {
			e.printStackTrace();
		}

		List<Completor> completors = new LinkedList<Completor>();
		String[] commands = new String[super.getActions().size()];

		int index = 0;
		for (Command action : super.getActions()) {
			commands[index] = action.getCommandShortcuts().get(0);
			index++;
		}

		completors.add(new SimpleCompletor(commands));
		reader.addCompletor(new ArgumentCompletor(completors));

		try {
			reader.clearScreen();
			this.printActionsMenu();

			while ((inputLine = reader.readLine("> ")) != null) {
				String[] splittedInputLine = inputLine.split("\\s+");
				String command = splittedInputLine[0];

				String[] args = new String[splittedInputLine.length - 1];
				for (int i = 1; i < splittedInputLine.length; i++) {
					args[i - 1] = splittedInputLine[i];
				}

				for (Command action : super.getActions()) {
					if (action.getCommandShortcuts().contains(command)) {
						if (args.length > 0) {
							action.setArgumentsLine(inputLine
									.substring(inputLine.indexOf(args[0])));
						}
						action.execute(args);
						break;
					}
				}
				reader.printNewline();
				this.printActionsMenu();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
